<?php
$className = "User";
@include_once "installableInterface.inc";
/* 
 * All operations concerning a single user
 * are to be handled by the User class.
 */
class User implements Installable {
    private $id = "";
    private $fname = "";
    private $lname = "";
    private $mnames = "";
    private $initials = "";
    private $email = "";
    private $pass = "";
    private $status = "";
    private $webpage = "";
    private $info = "";
    private $groups = null;
    private $db = null;
    private $userObjectStatus = "constructed";
    /**
     * The minimal constructor expects at least a Database object.
     *
     * @param Database $db
     */
    public function __construct() {
        $argv = func_get_args();
        switch( func_num_args() )
        {
            default:
            case 1:
                list($db) = $argv;
                self::defConstructor($db);
                break;
            case 2:
                list($db,$id) = $argv;
                self::idConstructor($db,$id);
                break;
            case 3:
                list($db,$email,$pass) = $argv;
                self::emailPassConstructor($db,$email,$pass);
                break;
            case  9:
                list($db,$fname,$middles,$lname,$initials,$email,$pass,$status,$info) = $argv;
                self::fullDataConstructor($db,$fname,$middles,$lname,$initials,$email,$pass,$status,$info);
                break;
            case  10:
                list($db,$fname,$middles,$lname,$initials,$email,$pass,$status,$info,$webpage) = $argv;
                self::fullDataConstructor($db,$fname,$middles,$lname,$initials,$email,$pass,$status,$info,$webpage);
                break;
            case 11:
                list($db,$fname,$middles,$lname,$initials,$email,$pass,$status,$info,$webpage,$id) = $argv;
                self::fullDataConstructor($db,$fname,$middles,$lname,$initials,$email,$pass,$status,$info,$webpage,$id);
                break;
        }
    }
    /**
     * The minimal constructor expects at least a Database object.
     *
     * @param Database $db
     */
    private function defConstructor($db) {
        $this->db = $db;
    }
    /**
     * This constructor initializes the user object with data
     * given the email address (login) and the password
     *
     * @param Database $db
     * @param String $email
     * @param String $pass
     */
    private function emailPassConstructor($db,$email, $pass) {
        $this->db = $db;
        $this->loadUserByEmailPass($email, $pass);
    }
    /**
     * This constructor initializes the user object with data
     * given the database user id.
     *
     * @param Database $db
     * @param String $id
     */
    private function idConstructor($db,$id) {
        $this->db = $db;
        $this->loadUserByID($id);
    }
    /**
     * The constructor initializes the user object with the values provided
     * where id is optional.
     *
     * @param Database $db
     * @param String $fname
     * @param String $middles
     * @param String $lname
     * @param String $initials
     * @param String $email
     * @param String $pass
     * @param String $status
     * @param String $webpage optional
     * @param String $id optional
     */
    private function fullDataConstructor($db,$fname,$mnames,$lname,$initials,$email,$pass,$status,$info,$webpage="",$id="-1") {
        $this->db = $db;
        $this->id = $id;
        $this->fname = $fname;
        $this->mnames= $mnames;
        $this->lname = $lname;
        $this->initials = $initials;
        $this->email = $email;
        $this->status = $status;
        $this->info = $info;
        $this->setPassword($pass);
        $this->webpage = $webpage;
        $this->userObjectStatus = "filled";
    }
    /**
     * Changes the password for the user currently represented by the user object.
     * @param String $oldPass
     * @param String $newPass
     * @param String $newPass
     */
    public function changePassword($oldPass, $newPass, $newPass) {

    }
    /**
     * This function checks whether the user currently represented by this
     * object is an administrator or not.
     * @return boolean true if is admin false otherwise.
     */
    public function isAdmin() {
        return(false);
    }

    /**
     * Fills the current user object with data from the database
     * if the supplied ID is valid.
     * @param <number> $id: user id as supplied by the autonumber during user creation
     */
    private function loadUserByID($id) {
        $sql = "SELECT * FROM Users WHERE ID=$id";
        $ud = $this->db->getResult($sql);
        if($ud) {
            $ud = $ud[0];
            $this->id = $ud['ID'];
            $this->fname = $ud['firstName'];
            $this->mnames= $ud['middleNames'];
            $this->lname = $ud['lastName'];
            $this->initials = $ud['initials'];
            $this->email = $ud['email'];
            $this->status = $ud['status'];
            $this->setPassword($ud['password']);
            $this->webpage = $ud['webPage'];
            $this->info = $ud['info'];
            $this->userObjectStatus = "filled";
        } else {
            $this->userObjectStatus = "failed";
        }
    }

    /**
     * Fills the current user object with the user data
     * from the database if email and pass are valid
     * @param <string> $email: the email of the user
     * @param <string> $pass: the password clear text or sha1 hashed
     */
    private function loadUserByEmailPass($email,$pass) {
        $this->setPassword($pass);
        $sql = "SELECT * FROM Users WHERE email='$email' AND password='$this->pass'";
        $ud = $this->db->getResult($sql);
        if($ud) {
            $ud = $ud[0];
            $this->id = $ud['ID'];
            $this->fname = $ud['firstName'];
            $this->mnames= $ud['middleNames'];
            $this->lname = $ud['lastName'];
            $this->initials = $ud['initials'];
            $this->email = $ud['email'];
            $this->status = $ud['status'];
            $this->setPassword($ud['password']);
            $this->webpage = $ud['webPage'];
            $this->info= $ud['info'];
            $this->userObjectStatus = "filled";
        } else
            $this->userObjectStatus = "failed";
    }

    /**
     * Creates a user belonging to the specified group
     * with the data currently present in the User object
     * @param <string> $group: e.g. administrator
     */
    public function createUser($group) {
        //Some variable checking should be done here
        $sql =  "   INSERT INTO Users
                    (firstName,middleNames,lastName,initials,email,status,webPage,password,info)
                    VALUES( '{$this->fname}','{$this->mnames}','{$this->lname}',
                            '{$this->initials}','{$this->email}','{$this->status}','" . mysql_real_escape_string($this->webpage) . "',
                            '{$this->pass}','" . mysql_real_escape_string($this->info) . "'
                    )
                ";
        $res = $this->db->executeSQL($sql);
        if(!$res) {
            echo "\r\nError($res)\r\n$sql\r\n";
            echo mysql_error();
        } else {
            $d = mysql_insert_id($this->db->getDBResID());
            $this->id = $d;
        }
        if($res && ($group != null)) {
            @include_once('group.inc');
            $grp = new Group($this->db);
            $grp->getGroupByName($group);
            @include_once('member.inc');
            $member = new Member($this->db);
            $member->createMembership($this, $group);
        }
        if($res)
            $this->userObjectStatus = "filled";
        else
            $this->userObjectStatus = "failed";
    }

    /**
     * A user that drops out of the research group
     * may not be granted access to the data anymore
     * so the user should be deleted.
     * This function will take car of that.
     */
    public function deleteUser() {
        $sql = "UPDATE Users SET status = 'deleted' WHERE ID=" . $this->id;
        $rs = $this->db->executeSQL($sql);
        $sql = "DELETE FROM Members WHERE UserID=" . $this->id;
        $rs = $this->db->executeSQL($sql);
    }

    /**
     * In case a user should be completely removed from the database
     * E.g. falsifying data etc.
     * This function will delete every data that is associated with the
     * user including all measurements.
     */
    public function purgeUser() {
        echo"Purge user not yet implemented.<br>\r\n";
    }

    /**
     * If the table exists it can be dropped in case 
     * a reinstallation is neccessary for instance.
     * @param <link identifier> $db is the database handle. 
     */
    public function dropTable() {
        $sql = "DROP TABLE IF EXISTS `Users`";
        $rs = $this->db->executeSQL($sql);
    }

    /**
     * Initially creates the table Users when the database is installed.
     * @param <link identifier> $db is the database handle.
     */
    public function createTable() {
        $this->dropTable();
        $sql = "
            CREATE TABLE  `Users` (
              `ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
              `firstName` varchar(45) NOT NULL,
              `middleNames` varchar(255) DEFAULT NULL,
              `lastName` varchar(45) NOT NULL,
              `initials` varchar(5) DEFAULT NULL,
              `email` varchar(255) NOT NULL,
              `status` varchar(5) NOT NULL,
              `webPage` varchar(255) DEFAULT NULL,
              `password` char(40) NOT NULL,
              `info` text DEFAULT NULL,
              PRIMARY KEY (`ID`),
              UNIQUE KEY `emailK` (`email`),
              KEY `passK` (`password`)
            ) ENGINE=InnoDB DEFAULT CHARSET=latin1
        ";
        $rs = $this->db->executeSQL($sql);
        if(!$rs) {
            return(false);
        }
        return(true);
    }
    public function insertInitialData() {
        //return(""); //No initial data inserted.
    }

    /**
     *  Getter Methods follow
     *     
     */
    public function getID() {
        if($this->userObjectStatus != "failed")
            return($this->id);
        else
            return(false);
    }
    public function getfName() {
        if($this->userObjectStatus != "failed")
            return($this->fname);
        else
            return(false);
    }
    public function getlName() {
        if($this->userObjectStatus != "failed")
            return($this->lname);
        else
            return(false);
    }
    public function getmNames() {
        if($this->userObjectStatus != "failed")
            return($this->mnames);
        else
            return(false);
    }
    public function getInitials() {
        if($this->userObjectStatus != "failed")
            return($this->initials);
        else
            return(false);
    }
    public function getEmail() {
        if($this->userObjectStatus != "failed")
            return($this->email);
        else
            return(false);
    }
    public function getPassword() {
        if($this->userObjectStatus != "failed")
            return($this->pass);
        else
            return(false);
    }
    public function setPassword($unencrypted) {
        if(strlen($unencrypted) < 30) {
            $this->pass = sha1($unencrypted);
        } else {
            $this->pass = $unencrypted;
        }
    }
    public function getStatus() {
        if($this->userObjectStatus != "failed")
            return($this->status);
        else
            return(false);
    }
    public function getWebPage() {
        if($this->userObjectStatus != "failed")
            return($this->webpage);
        else
            return(false);
    }
    public function getInfo() {
        if($this->userObjectStatus != "failed")
            return($this->info);
        else
            return(false);
    }
    public function getGroups() {
        if($this->userObjectStatus != "failed")
            return($this->groups);
        else
            return(false);
    }
    public function getUserObjectStatus() {
        return($this->userObjectStatus);
    }
}
?>
